/**
 * API接口工具
 */

import { showError, showLoading, hideLoading } from './util.js'

/**
 * 云函数调用封装
 */
class CloudAPI {
  constructor() {
    this.timeout = 10000 // 默认超时时间10秒
  }

  /**
   * 调用云函数
   * @param {string} name - 云函数名称
   * @param {object} data - 请求数据
   * @param {object} options - 选项
   * @returns {Promise} 响应结果
   */
  async callFunction(name, data = {}, options = {}) {
    const { 
      showLoading: shouldShowLoading = false,
      loadingText = '请求中...',
      showError: shouldShowError = true,
      timeout = this.timeout
    } = options

    try {
      if (shouldShowLoading) {
        showLoading(loadingText)
      }

      const result = await this._callWithTimeout(name, data, timeout)
      
      if (shouldShowLoading) {
        hideLoading()
      }

      if (result.result.success) {
        return result.result
      } else {
        const error = new Error(result.result.message || '请求失败')
        error.code = result.result.code
        throw error
      }
    } catch (error) {
      if (shouldShowLoading) {
        hideLoading()
      }
      
      if (shouldShowError) {
        showError(error.message || '网络请求失败')
      }
      
      console.error(`云函数调用失败 [${name}]:`, error)
      throw error
    }
  }

  /**
   * 带超时的云函数调用
   * @param {string} name - 云函数名称
   * @param {object} data - 请求数据
   * @param {number} timeout - 超时时间
   * @returns {Promise} 响应结果
   */
  _callWithTimeout(name, data, timeout) {
    return new Promise((resolve, reject) => {
      const timer = setTimeout(() => {
        reject(new Error('请求超时'))
      }, timeout)

      wx.cloud.callFunction({
        name,
        data,
        success: (result) => {
          clearTimeout(timer)
          resolve(result)
        },
        fail: (error) => {
          clearTimeout(timer)
          reject(error)
        }
      })
    })
  }
}

// 创建API实例
const api = new CloudAPI()

/**
 * 用户相关API
 */
export const userAPI = {
  /**
   * 用户登录
   * @param {object} userInfo - 用户信息
   * @returns {Promise} 登录结果
   */
  async login(userInfo) {
    return await api.callFunction('login', { userInfo }, {
      showLoading: true,
      loadingText: '登录中...'
    })
  },

  /**
   * 获取用户信息
   * @returns {Promise} 用户信息
   */
  async getUserInfo() {
    return await api.callFunction('getUserInfo')
  },

  /**
   * 更新用户设置
   * @param {object} settings - 设置信息
   * @returns {Promise} 更新结果
   */
  async updateSettings(settings) {
    return await api.callFunction('updateUserSettings', { settings }, {
      showLoading: true,
      loadingText: '保存中...'
    })
  }
}

/**
 * 账单相关API
 */
export const billAPI = {
  /**
   * 添加账单
   * @param {object} billData - 账单数据
   * @returns {Promise} 添加结果
   */
  async addBill(billData) {
    return await api.callFunction('addBill', billData, {
      showLoading: true,
      loadingText: '保存中...'
    })
  },

  /**
   * 获取账单列表
   * @param {object} params - 查询参数
   * @returns {Promise} 账单列表
   */
  async getBills(params = {}) {
    return await api.callFunction('getBills', params)
  },

  /**
   * 更新账单
   * @param {string} billId - 账单ID
   * @param {object} billData - 账单数据
   * @returns {Promise} 更新结果
   */
  async updateBill(billId, billData) {
    return await api.callFunction('updateBill', { billId, ...billData }, {
      showLoading: true,
      loadingText: '更新中...'
    })
  },

  /**
   * 删除账单
   * @param {string} billId - 账单ID
   * @returns {Promise} 删除结果
   */
  async deleteBill(billId) {
    return await api.callFunction('deleteBill', { billId }, {
      showLoading: true,
      loadingText: '删除中...'
    })
  },

  /**
   * 批量删除账单
   * @param {Array} billIds - 账单ID数组
   * @returns {Promise} 删除结果
   */
  async deleteBills(billIds) {
    return await api.callFunction('deleteBills', { billIds }, {
      showLoading: true,
      loadingText: '删除中...'
    })
  }
}

/**
 * 分类相关API
 */
export const categoryAPI = {
  /**
   * 获取分类列表
   * @param {string} type - 分类类型 income/expense
   * @returns {Promise} 分类列表
   */
  async getCategories(type) {
    return await api.callFunction('getCategories', { type })
  },

  /**
   * 添加自定义分类
   * @param {object} categoryData - 分类数据
   * @returns {Promise} 添加结果
   */
  async addCategory(categoryData) {
    return await api.callFunction('addCategory', categoryData, {
      showLoading: true,
      loadingText: '添加中...'
    })
  },

  /**
   * 更新分类
   * @param {string} categoryId - 分类ID
   * @param {object} categoryData - 分类数据
   * @returns {Promise} 更新结果
   */
  async updateCategory(categoryId, categoryData) {
    return await api.callFunction('updateCategory', { categoryId, ...categoryData }, {
      showLoading: true,
      loadingText: '更新中...'
    })
  },

  /**
   * 删除分类
   * @param {string} categoryId - 分类ID
   * @returns {Promise} 删除结果
   */
  async deleteCategory(categoryId) {
    return await api.callFunction('deleteCategory', { categoryId }, {
      showLoading: true,
      loadingText: '删除中...'
    })
  }
}

/**
 * 统计相关API
 */
export const statisticsAPI = {
  /**
   * 获取统计概览
   * @param {object} params - 查询参数
   * @returns {Promise} 统计数据
   */
  async getStatistics(params) {
    return await api.callFunction('getStatistics', params, {
      showLoading: true,
      loadingText: '加载中...'
    })
  },

  /**
   * 获取图表数据
   * @param {object} params - 查询参数
   * @returns {Promise} 图表数据
   */
  async getChartData(params) {
    return await api.callFunction('getChartData', params, {
      showLoading: true,
      loadingText: '生成图表中...'
    })
  },

  /**
   * 获取趋势数据
   * @param {object} params - 查询参数
   * @returns {Promise} 趋势数据
   */
  async getTrendData(params) {
    return await api.callFunction('getTrendData', params)
  }
}

/**
 * 预算相关API
 */
export const budgetAPI = {
  /**
   * 设置预算
   * @param {string} month - 月份
   * @param {number} amount - 预算金额
   * @returns {Promise} 设置结果
   */
  async setBudget(month, amount) {
    return await api.callFunction('setBudget', { month, amount }, {
      showLoading: true,
      loadingText: '设置中...'
    })
  },

  /**
   * 获取预算信息
   * @param {string} month - 月份
   * @returns {Promise} 预算信息
   */
  async getBudget(month) {
    return await api.callFunction('getBudget', { month })
  },

  /**
   * 获取预算使用情况
   * @param {string} month - 月份
   * @returns {Promise} 使用情况
   */
  async getBudgetUsage(month) {
    return await api.callFunction('getBudgetUsage', { month })
  },

  /**
   * 删除预算
   * @param {string} month - 月份
   * @returns {Promise} 删除结果
   */
  async deleteBudget(month) {
    return await api.callFunction('deleteBudget', { month }, {
      showLoading: true,
      loadingText: '删除中...'
    })
  }
}

/**
 * 数据管理相关API
 */
export const dataAPI = {
  /**
   * 导出数据
   * @param {object} params - 导出参数
   * @returns {Promise} 导出结果
   */
  async exportData(params) {
    return await api.callFunction('exportData', params, {
      showLoading: true,
      loadingText: '导出中...',
      timeout: 30000 // 导出可能需要更长时间
    })
  },

  /**
   * 备份数据
   * @returns {Promise} 备份结果
   */
  async backupData() {
    return await api.callFunction('backupData', {}, {
      showLoading: true,
      loadingText: '备份中...',
      timeout: 30000
    })
  },

  /**
   * 恢复数据
   * @param {string} backupId - 备份ID
   * @returns {Promise} 恢复结果
   */
  async restoreData(backupId) {
    return await api.callFunction('restoreData', { backupId }, {
      showLoading: true,
      loadingText: '恢复中...',
      timeout: 30000
    })
  },

  /**
   * 获取备份列表
   * @returns {Promise} 备份列表
   */
  async getBackups() {
    return await api.callFunction('getBackups')
  },

  /**
   * 删除备份
   * @param {string} backupId - 备份ID
   * @returns {Promise} 删除结果
   */
  async deleteBackup(backupId) {
    return await api.callFunction('deleteBackup', { backupId }, {
      showLoading: true,
      loadingText: '删除中...'
    })
  }
}

/**
 * 批量请求工具
 */
export const batchAPI = {
  /**
   * 并行执行多个请求
   * @param {Array} requests - 请求数组
   * @returns {Promise} 所有请求结果
   */
  async parallel(requests) {
    try {
      const results = await Promise.all(requests)
      return results
    } catch (error) {
      console.error('批量请求失败:', error)
      throw error
    }
  },

  /**
   * 串行执行多个请求
   * @param {Array} requests - 请求数组
   * @returns {Promise} 所有请求结果
   */
  async series(requests) {
    const results = []
    for (const request of requests) {
      try {
        const result = await request()
        results.push(result)
      } catch (error) {
        console.error('串行请求失败:', error)
        throw error
      }
    }
    return results
  }
}

/**
 * 请求重试工具
 */
export const retryAPI = {
  /**
   * 重试请求
   * @param {Function} requestFn - 请求函数
   * @param {number} maxRetries - 最大重试次数
   * @param {number} delay - 重试延迟时间
   * @returns {Promise} 请求结果
   */
  async retry(requestFn, maxRetries = 3, delay = 1000) {
    let lastError
    
    for (let i = 0; i <= maxRetries; i++) {
      try {
        return await requestFn()
      } catch (error) {
        lastError = error
        
        if (i < maxRetries) {
          console.warn(`请求失败，${delay}ms后重试 (${i + 1}/${maxRetries}):`, error.message)
          await this._delay(delay)
          delay *= 2 // 指数退避
        }
      }
    }
    
    throw lastError
  },

  /**
   * 延迟函数
   * @param {number} ms - 延迟时间（毫秒）
   * @returns {Promise} 延迟Promise
   */
  _delay(ms) {
    return new Promise(resolve => setTimeout(resolve, ms))
  }
}

/**
 * 缓存工具
 */
export const cacheAPI = {
  cache: new Map(),
  
  /**
   * 带缓存的请求
   * @param {string} key - 缓存键
   * @param {Function} requestFn - 请求函数
   * @param {number} ttl - 缓存时间（毫秒）
   * @returns {Promise} 请求结果
   */
  async withCache(key, requestFn, ttl = 5 * 60 * 1000) {
    const cached = this.cache.get(key)
    
    if (cached && Date.now() - cached.timestamp < ttl) {
      return cached.data
    }
    
    try {
      const data = await requestFn()
      this.cache.set(key, {
        data,
        timestamp: Date.now()
      })
      return data
    } catch (error) {
      // 如果有缓存数据，在请求失败时返回缓存
      if (cached) {
        console.warn('请求失败，返回缓存数据:', error.message)
        return cached.data
      }
      throw error
    }
  },

  /**
   * 清除缓存
   * @param {string} key - 缓存键，不传则清除所有
   */
  clearCache(key) {
    if (key) {
      this.cache.delete(key)
    } else {
      this.cache.clear()
    }
  },

  /**
   * 获取缓存大小
   * @returns {number} 缓存项数量
   */
  getCacheSize() {
    return this.cache.size
  }
}

/**
 * 网络状态检查
 */
export const networkAPI = {
  /**
   * 检查网络连接
   * @returns {Promise<boolean>} 是否有网络连接
   */
  async checkConnection() {
    try {
      const networkType = await this.getNetworkType()
      return networkType.networkType !== 'none'
    } catch (error) {
      return false
    }
  },

  /**
   * 获取网络类型
   * @returns {Promise<object>} 网络类型信息
   */
  getNetworkType() {
    return new Promise((resolve, reject) => {
      wx.getNetworkType({
        success: resolve,
        fail: reject
      })
    })
  },

  /**
   * 监听网络状态变化
   * @param {Function} callback - 回调函数
   */
  onNetworkStatusChange(callback) {
    wx.onNetworkStatusChange(callback)
  },

  /**
   * 取消监听网络状态变化
   */
  offNetworkStatusChange() {
    wx.offNetworkStatusChange()
  }
}

// 默认导出API实例
export default api